from functools import total_ordering
from unittest import result
from models.ios_widget import model
from datetime import datetime, timedelta
from helpers.ios_widget import setting
from lib.qiniu_url_unixtime import qiniu_url_unixtime
import operator

tb_analysised_data = model.AnalysisUserWidgetList()
tb_analysis_view = model.AnalysisWidgetView()
tb_analysis_click = model.AnalysisWidgetClick()
tb_module = model.ComponentLibraryModuleList()
tb_analysis_complete_set = model.AnalysisWidgetCompleteSet()



def get_analysis_data(start_date:datetime=None, end_date:datetime=None, skip:int=0, limit:int=10, search_code:str="click_rate_desc", n=1):
    if start_date:
        if end_date:
            res, count = get_data(start_date=start_date, end_date=end_date, search_code=search_code, skip=skip, limit=limit)
        else:
            res, count = get_data(start_date=start_date, end_date=start_date, search_code=search_code, skip=skip, limit=limit)
    else:
        start_date = datetime.now() - timedelta(days=n)
        end_date = datetime.now() - timedelta(days=1)
        res, count= get_data(start_date=start_date, end_date=end_date, search_code=search_code, skip=skip, limit=limit)
    return {
        'count': count,
        'list': res
    }


def get_data(start_date: datetime, end_date: datetime, search_code: str, skip: int = 0, limit: int = 10):
    start_time = datetime(start_date.year, start_date.month, start_date.day)
    end_time = datetime(end_date.year, end_date.month,
                        end_date.day, 23, 59, 59)
    
    # 取出指定时间段的数据,并计算点击率，完成设置率，存储在字典里
    init_dict = search_data(start_time, end_time, tb_analysised_data, search_code=0)

    # 取出独立用户数，根据oid 添加到目标数据列表中
    view_count_user_dict = search_data(start_time, end_time, tb_analysis_view, search_code=1)
    click_count_user_dict = search_data(start_time, end_time, tb_analysis_click, search_code=1)
    complete_set_count_user_dict = search_data(start_time, end_time, tb_analysis_complete_set, search_code=1)

    # 合并数据
    result_dict = combine_data_dict(init_dict, view_count_user_dict, click_count_user_dict, complete_set_count_user_dict)

    # 对目标数据列表进行排序，并返回指定的分页结果
    result_list, count = sort_format_data(data=result_dict, sort_code=search_code, skip=skip, limit=limit)
    return result_list, count


def sort_format_data(data:dict, sort_code:str, skip:int, limit:int): 
    # 排序 默认降序
    sort_options = {
        'click_rate_desc': ('click_rate', True),
        'click_rate_asc': ('click_rate', False),
        'complete_set_rate_desc': ('complete_set_rate', True),
        'complete_set_rate_asc': ('complete_set_rate', False)
    }

    i, sybol = sort_options.get(sort_code, ('click_rate', True))
    sorted_data_items = sorted(data.items(), key=lambda item: item[1][i], reverse=sybol)
    # 结果总数
    count = len(sorted_data_items) 
    sorted_data = []
    # 格式化
    for key, value in sorted_data_items[skip:skip + limit]:
        result = tb_module.find_one({'_id': key})
        r = {}
        r['oid'] = key
        r['view_count'] = f"{value['view_count']:<4} /&nbsp&nbsp{value['view_count_user']:<4}"
        r['click_count'] = f"{value['click_count']:<4} /&nbsp&nbsp{value['click_count_user']:<4}"
        r['complete_set_count'] = f"{value['complete_set_count']:<4} /&nbsp&nbsp{value['complete_set_count_user']:<4}"
        r['click_rate'] = value['click_rate']
        r['complete_set_rate'] = value['complete_set_rate']

        r['name'] = result['name']
        r['widget_type'] = result['widget_type']
        r['thumb_url'] = qiniu_url_unixtime(setting.QINIU_HOST, result.get('thumb_url', ''))
        sorted_data.append(r)
    return sorted_data, count


def search_data(start_time: datetime, end_time: datetime, mongo_collection, search_code:int=0):
    # 构造查询条件

    query_pipelint = [
        {
            '$match': {
                'atime': {
                    '$gte': start_time,
                    '$lte': end_time
                }
            }
        },
        {
            '$group': {  # 合并数据（oid为唯一）
                '_id': '$oid',
                'total_view_count': {'$sum': '$view_count'},
                'total_click_count': {'$sum': {'$toInt': '$click_count'}},
                'total_complete_set_count': {'$sum': {'$toInt': '$complete_set_count'}}
            }
        }
    ]

    unique_user_pipeline = [
        {
            '$match': {
                'atime': {
                    '$gte': start_time,
                    '$lte': end_time
                }
            }
        },
        {
            '$group': {
                '_id': {
                    'oid': '$oid',
                    'open_id': '$open_id'
                }
            }
        },
        {
            '$group': {
                '_id': '$_id.oid',
                'count': {'$sum': 1}
            }
        }
    ]
    
    r = {}  # 存储去重后的数据
    if search_code == 0:
        records = list(mongo_collection.aggregate(query_pipelint))
        for f in records:
            oid = f['_id']
            view_count = f['total_view_count']
            click_count = f['total_click_count']
            complete_set_count = f['total_complete_set_count']
            # 计算点击率、完成设置率，并添加到目标数据列表中
            click_rate = get_rate(click_count, view_count)
            complete_set_rate = get_rate(complete_set_count, click_count)

            data_dict = {}
            data_dict['view_count'] = view_count
            data_dict['click_count'] = click_count
            data_dict['complete_set_count'] = complete_set_count
            data_dict['click_rate'] = click_rate
            data_dict['complete_set_rate'] = complete_set_rate
            r[oid] = data_dict
    elif search_code == 1:
        records = list(mongo_collection.aggregate(unique_user_pipeline))
        for f in records:
            oid = f['_id']
            data_count = f['count']
            r[oid] = data_count
    return r


def combine_data_dict(init_count_dict:dict, view_user_dict: dict,  click_user_dict: dict,  complete_set_user_dict: dict) -> dict:
    for key in init_count_dict.keys():
        init_count_dict[key]['view_count_user'] = get_value(view_user_dict,key)
        init_count_dict[key]['click_count_user'] = get_value(click_user_dict,key) 
        init_count_dict[key]['complete_set_count_user'] = get_value(complete_set_user_dict,key) 
    return init_count_dict


def get_rate(up, down):
    if not down:
        return 0.0000
    r = up/down
    return float(f"{r:.4f}")


def get_value(dic, key):
    return dic[key] if key in dic else 0

if __name__ == "__main__":
    start_time = datetime(2023, 12, 18)
    result = get_analysis_data(n=30)
    print(result['count'])
    for f in result['list']:
        print(f['click_rate'])
